package com.tdam.CommunicationManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ViewAnimator;




public abstract class AnimatedActivity extends ListActivity 
{

	protected ViewAnimator views;
	protected InfoAdapter _adapter;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);

	}


	public void nextView()
	{
		views.setInAnimation(inFromRightAnimation());
		views.setOutAnimation(outToLeftAnimation());
		views.showNext();
	}

	public void previousView()
	{
		views.setInAnimation(inFromLeftAnimation());
		views.setOutAnimation(outToRightAnimation());
		views.showPrevious();		
	}

	public final Animation inFromRightAnimation() {
		Animation inFromRight = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT,  +1.0f, Animation.RELATIVE_TO_PARENT,  0.0f,
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
		);
		inFromRight.setDuration(200);
		inFromRight.setInterpolator(new AccelerateInterpolator());
		return inFromRight;
	}
	
	public final Animation outToLeftAnimation() {
		Animation outtoLeft = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,  -1.0f,
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
		);
		outtoLeft.setDuration(200);
		outtoLeft.setInterpolator(new AccelerateInterpolator());
		return outtoLeft;
	}
	 
	public final Animation inFromLeftAnimation() {
		Animation inFromLeft = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT,  -1.0f, Animation.RELATIVE_TO_PARENT,  0.0f,
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
		);
		inFromLeft.setDuration(200);
		inFromLeft.setInterpolator(new AccelerateInterpolator());
		return inFromLeft;
	}
	
	public final Animation outToRightAnimation() {
		Animation outtoRight = new TranslateAnimation(
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,  +1.0f,
				Animation.RELATIVE_TO_PARENT,  0.0f, Animation.RELATIVE_TO_PARENT,   0.0f
		);
		outtoRight.setDuration(200);
		outtoRight.setInterpolator(new AccelerateInterpolator());
		return outtoRight;
	}	
	

	
	protected class InfoAdapter <Item,ItemHolder extends Holder> 
						extends BaseAdapter
	{
		ArrayList<Item> items;
		ArrayList<Item> originalItems;
		InfoFilter myFilter;
		
		private LayoutInflater _inflater;
		private int itemResource;
		private Class holderClass;
		public InfoAdapter(Context context, int resource,Class holderClass)
		{
			items= new ArrayList<Item>();
			originalItems=new ArrayList<Item>();
			myFilter=new InfoFilter();
			_inflater = LayoutInflater.from(context);
			itemResource=resource;
			this.holderClass=holderClass;
			
		}
		
		public void addItem(Item newItem)
		{
			synchronized (this)
			{
				items.add(newItem);
				originalItems.add(newItem);
			}
		}

		public void addItems(ArrayList<Item> items)
		{
			synchronized (this)
			{
				items.addAll(items);
				originalItems.addAll(items);
			}
		}
		
		
		
		public void addFirst(Item newItem)
		{
			synchronized (this)
			{
				items.add(0,newItem);
				originalItems.add(0,newItem);
			}
		}
		
		public void clear()
		{
			synchronized (this)
			{
				items.clear();
				originalItems.clear();
			}
		}
		
		public void remove(int position)
		{
			synchronized (this)
			{
				originalItems.remove(items.get(position));
				items.remove(position);
			}
		}
		
		
		@Override
		public int getCount() 
		{
			return items.size();
		}

		public int getAllCount() 
		{
			return originalItems.size();
		}
		
		
		@Override
		public Object getItem(int arg0) 
		{
			return items.get(arg0);
		}

		public Object getItemFromOriginal(int arg0) 
		{
			return originalItems.get(arg0);
		}
		
		
		@Override
		public long getItemId(int arg0) 
		{
			return arg0;
		}

		public void sort(Comparator ItemComparator)
		{
			Collections.sort(items, ItemComparator);
			Collections.sort(originalItems, ItemComparator);
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			ItemHolder holder = null;
			if (convertView == null) 
			{
				convertView = _inflater.inflate(itemResource, null);
				try {
					holder = (ItemHolder) holderClass.newInstance();
					holder.link(convertView);
					convertView.setTag(holder);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					e.printStackTrace();
				}
			}else
			{
				holder = (ItemHolder) convertView.getTag();
			}
			holder.fill(items.get(position));
			return convertView;
		}

	    public Filter getFilter() 
	    {
	        return myFilter;
	    }		
		
		
	    private class InfoFilter extends Filter {
	        @Override
	        protected FilterResults performFiltering(CharSequence prefix) {
	            FilterResults results = new FilterResults();

	            if (prefix == null || prefix.length() == 0) {
	                synchronized (InfoAdapter.this) {
	                    ArrayList<Item> list = new ArrayList<Item>(originalItems);
	                    results.values = list;
	                    results.count = list.size();
	                }
	            } else {
	                String prefixString = prefix.toString().toLowerCase();

	                final ArrayList<Item> values = originalItems;
	                final int count = values.size();

	                final ArrayList<Item> newValues = new ArrayList<Item>(count);

	                for (int i = 0; i < count; i++) {
	                    final Item value = values.get(i);
	                    final String valueText = value.toString().toLowerCase();

	                    // First match against the whole, non-splitted value
	                    if (valueText.startsWith(prefixString)) {
	                        newValues.add(value);
	                    } else {
	                        final String[] words = valueText.split(" ");
	                        final int wordCount = words.length;

	                        for (int k = 0; k < wordCount; k++) {
	                            if (words[k].startsWith(prefixString)) {
	                                newValues.add(value);
	                                break;
	                            }
	                        }
	                    }
	                }

	                results.values = newValues;
	                results.count = newValues.size();
	            }

	            return results;
	        }
	        @Override
	        protected void publishResults(CharSequence constraint, FilterResults results)
	        {
	            items = ((ArrayList<Item>) results.values);
	            if (results.count > 0) {
	                notifyDataSetChanged();
	            } else {
	                notifyDataSetInvalidated();
	            }	            
	        }
	    }		
	}	
}